from paramiko import Transport, SFTPClient
import logging
import os, time
logging.basicConfig(format='%(asctime)s - %(pathname)s[line:%(lineno)d] - %(levelname)s: %(message)s',level=logging.DEBUG)
class ftps():
    def __init__(self):
        self.setting = "ftps"
        self.setMap = {}
        self.fileList=[]
        self.before = None
        self.host=None
        self.port=None
        self.conn = None
        self.sftp = None
        self.level=None
        self.listendir=None
        self.aimdir=None
        self.username=None
        self.password=None
    def loadSetting(self):
        try:
            with open(self.setting, 'r') as f:
                for line in f.readlines():
                    if line != None and line != '' and line != '\n' and (' ' not in line):
                        settings = line.strip().split('=')
                        self.setMap[settings[0]] = settings[1]
                    else:
                        continue
            self.level=self.setMap['level']
            self.listendir = 'listendir'+self.level
            self.aimdir = 'aimdir' + self.level
            self.username="username" + self.level
            self.password="password" + self.level
            self.host="host" + self.level
            self.port="port" + self.level
        except Exception:
            self.logConstructor("error", "setting file is not exists!")
        self.logConstructor('info', 'get the listendir ' + self.setMap[self.listendir])
        if os.path.exists(self.setMap[self.listendir]):
            self.before = dict([(f, os.stat(self.setMap[self.listendir]+'/' + f ).st_mtime) for f in os.listdir(self.setMap[self.listendir])])
            self.listenDir()
        else:
            self.logConstructor("error", "The listening dir is not exists!")
    def logConstructor(self, level, msg):
        if level == 'debug':
            logging.debug(msg)
        elif level == 'info':
            logging.info(msg)
        elif level == 'warn':
            logging.warning(msg)
        else:
            logging.error(msg)
    def listenDir(self):
        if os.path.exists(self.setMap[self.listendir]):
            while 1:
                time.sleep(1)
                current = dict([(f, os.stat(self.setMap[self.listendir]+'/' + f ).st_mtime) for f in os.listdir(self.setMap[self.listendir])])
                added = dict([(f, os.stat(self.setMap[self.listendir]+'/' + f ).st_mtime) for f in current if not f in self.before])
                if added:
                    for k, v in added.items():
                        self.before[k] = v
                        self.uploadFile(k,v)
                    added = {}

                    continue
                '''if removed:
                    for k, v in removed.items():
                        self.before[k] = v
                    removed = {}
                    continue'''
                copyFlag=False
                if not added:
                    for key in current.keys():
                        if current[key] != self.before[key]:
                            self.logConstructor("warn", key + "'s time has changed " + str(self.before[key]) +  " to " + str(current[key]))
                            self.uploadFile(key, current[key])
                            copyFlag = True
                            break
                    if copyFlag == True:
                        self.before = current
                        copyFlag = False
        else:
            self.logConstructor("error", "The listening dir is not exist!")
    def path(self, file):
        return self.setMap[self.listendir] + '/' + file
    def uploadFile(self, file, time):
        self.sftp = self.login()
        if self.dirExist(self.setMap[self.aimdir] + file):
            self.sftp.put(self.path(file), self.setMap[self.aimdir] + file)
            self.logConstructor("info", self.path(file) + " is uploading!")
    def login(self):
        self.logConstructor("info", "Try to connect the ftp server in " + self.setMap[self.host])
        username = self.setMap[self.username]
        password = self.setMap[self.password]
        self.conn = Transport((self.setMap[self.host],int(self.setMap[self.port])))
        self.conn.connect(username=username, password=password)
        return SFTPClient.from_transport(self.conn)
    def dirExist(self, file):
        try:
            self.sftp.stat(file)
            self.logConstructor("warn", file + "is existed in the server!")
            self.sftp.remove(file)
            self.logConstructor("info", "The existed file has been deleted!")
            return True
        except:
            self.logConstructor("info", "upload func is ready...")
            return True
    def solve(self):
        self.loadSetting()
if __name__=='__main__':
    f = ftps()
    f.solve()
